package ddz.logic.game;

import ch.qos.logback.classic.Logger;
import com.kaka.notice.Message;
import com.kaka.notice.annotation.Handler;
import ddz.constants.Crypto;
import ddz.constants.ErrCode;
import ddz.constants.ErrLevel;
import ddz.constants.OpCode;
import ddz.core.*;
import ddz.db.dao.TableDao;
import ddz.db.dao.UserDao;
import ddz.db.entity.ItemInfo;
import ddz.db.entity.UserInfo;
import ddz.db.service.TableTokenService;
import ddz.logic.ItemUtils;
import ddz.net.LogicDataHandler;
import ddz.net.ProtocolMessage;
import ddz.protos.GameJiabei;
import ddz.utils.JsonUtils;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
 * 加倍
 *
 * @author zkpursuit
 */
@Handler(cmd = OpCode.cmd_jiabei, type = String.class)
public class JiaBeiHandler extends LogicDataHandler {

    private static final Logger logger = (Logger) LoggerFactory.getLogger(JiaBeiHandler.class);

    @Override
    public void execute(ProtocolMessage msg) throws Exception {
        GameJiabei.CsJiabei reqData = (GameJiabei.CsJiabei) msg.getBody();
        TableTokenService optTokenService = this.retrieveProxy(TableTokenService.class);
        TableToken tokenInfo = optTokenService.parseToken(reqData.getToken());
        TableDao tableDao = this.retrieveProxy(TableDao.class);
        Table table = tableDao.getDesk(tokenInfo.getDeskId());
        if (table == null) {
            logger.error("玩家（" + msg.uid() + "）未加入任何房间");
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.no_join_room);
            return;
        }
        Player player = table.getPlayerByUid(msg.uid());
        if (player == null) {
            logger.error("玩家 [{}：{}] 在 [{}] 房间中无对应的数据", player.getSeatIndex(), msg.uid(), table.getId());
            sendError(msg.ctx(), opcode(), ErrLevel.ERROR, ErrCode.data_err);
            return;
        }
//        if (desk.getStep() != tokenInfo.getStep()) {
//            logger.error("玩家 [{}：{}] 在 [{}] 中不能进行加倍操作", player.getSeatIndex(), msg.uid(), desk.getId());
//            sendError(msg.ctx(), opcode(), ErrLevel.WARN, ErrCode.illegal_operation);
//            return;
//        }
        if (table.isAlreadyJiabei(player.getSeatIndex())) {
            logger.error("玩家 [{}：{}] 在 [{}] 中已进行加倍操作", player.getSeatIndex(), msg.uid(), table.getId());
            sendError(msg.ctx(), opcode(), ErrLevel.WARN, ErrCode.illegal_operation);
            return;
        }
        int optype = reqData.getOpt();
        OptType optType;
        if (optype == OptType.jiabei1.getId()) {
            optType = OptType.jiabei1;
        } else if (optype == OptType.jiabei2.getId()) {
            optType = OptType.jiabei2;
            if (player.getUid() > Integer.MAX_VALUE && player.getTimeoutCount() != TrusteeType.robot.getTimeoutCount()) {
                UserDao userDao = this.retrieveProxy(UserDao.class);
                UserInfo userInfo = userDao.getUserInfo(player.getUid());
                List<ItemInfo> userItemList = ItemUtils.parseItemList(userInfo.getItems());
                if (!ItemUtils.hasPropItem(userItemList, 8, 1)) {
                    logger.error("玩家 [{}：{}] 在 [{}] 中进行超级加倍，加倍卡不足", player.getSeatIndex(), msg.uid(), table.getId());
                    sendError(msg.ctx(), opcode(), ErrLevel.WARN, ErrCode.jiabei_not_enough);
                    return;
                }
                ItemUtils.filterItems(userItemList);
                ItemUtils.delItem(userItemList, 8, 1, userInfo);
                userInfo.setItems(JsonUtils.toJsonString(userItemList));
                userDao.insertOrUpdateUser(userInfo);
            }
        } else {
            optType = OptType.buJiabei;
        }

        table.addOptRecord(new OptRecord(optType, player.getSeatIndex()));

        if (logger.isInfoEnabled()) {
            logger.info("玩家 [{}：{}] 在 [{}] 房间中 [{}]，倍率为：{}", player.getSeatIndex(), msg.uid(), table.getId(), optType, table.getMultiple());
        }

        Player[] players = table.getPlayers();
        int[] beis = table.getMultiple();
        for (Player member : players) {
            byte[] respBytes = GameJiabei.ScJiabei.newBuilder()
                    .setSeat(player.getSeatIndex())
                    .setOpt(optType.getId())
                    .setBei(beis[member.getSeatIndex()])
                    .build().toByteArray();
            this.sendData(member.getUid(), Crypto.isCrypto, Integer.parseInt(OpCode.cmd_jiabei), respBytes);
        }

        if (table.allAlreadyJiabei()) {
            table.setState(TableState.playing);
            sendMessage(new Message(OpCode.cmd_show_opts, table));
            //更新记牌器
            sendMessage(new Message(OpCode.cmd_counter, table));
        } else {
            tableDao.insertOrUpdateDesk(table);
        }
    }
}
